﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization;
using System.IO;

namespace Kollektiv.Extension
{
    public static class System_IO_Stream
    {
        /// <summary>
        /// Deserializes a stream containing a data contract object.
        /// </summary>
        /// <typeparam name="T">Type of the object which should be deserialized</typeparam>
        /// <param name="serialized">Stream containing the serialized object.</param>
        /// <returns>Deserialized object.</returns>
        public static T DeserializeDataContract<T>(this Stream stream) where T : class
        {
            DataContractSerializer serializer = new DataContractSerializer(typeof(T));
            return serializer.ReadObject(stream) as T;
        }

        /// <summary>
        /// Gets the string content of a stream.
        /// </summary>
        /// <param name="stream">Stream containing string.</param>
        /// <returns>Thre string</returns>
        public static string AsString(this Stream stream)
        {
            return stream.AsString(Encoding.Default);
        }

        /// <summary>
        /// Gets the string content of a stream.
        /// </summary>
        /// <param name="stream">Stream containing string.</param>
        /// <param name="encoding">Encoding of the contained string.</param>
        /// <returns>Thre string</returns>
        public static string AsString(this Stream stream, Encoding encoding)
        {
            StringBuilder sb = new StringBuilder();

            stream.Position = 0;

            while(stream.Position < stream.Length - 1)
            {
                int readLength = Convert.ToInt32(stream.Position + 4096 < stream.Length ? 4096 : stream.Length - stream.Position);
                byte[] buf = new byte[readLength];

                stream.Read(buf, 0, readLength);

                sb.Append(encoding.GetString(buf));
            }

            return sb.ToString();
        }
    }
}
